package main

import (
	"bufio"
	"database/sql"
	"fmt"
	"log"
	"math/rand"
	"os"
	"strconv"
	"strings"
	"time"

	_ "github.com/go-sql-driver/mysql"
)

type Client struct {
	connstr string
	driver  string
	dbconn  *sql.DB
}

func NewClient(user, pass, dbname, protocol string) *Client {
	connstr := fmt.Sprintf("%s:%s@%s/%s?charset=utf8", user, pass, protocol, dbname)
	return &Client{connstr, "mysql", nil}
}

func (cli *Client) Conn() error {
	db, err := sql.Open(cli.driver, cli.connstr)
	if err != nil {
		fmt.Println("failed to open database ", err)
		return err
	}
	cli.dbconn = db
	return cli.dbconn.Ping()
}

func (cli *Client) Run() {
	reader := bufio.NewReader(os.Stdin)
	fmt.Println("Welcome to mysql client ")
	for {
		fmt.Printf("lbl-mysql>")
		sqlstr, err := reader.ReadString('\n')
		if err != nil {
			log.Panic("failed to ReadString ", err)
		}
		sqlstr = strings.Trim(sqlstr, "\r\n")
		sqls := []byte(sqlstr)

		if sqlstr == "?" || sqlstr == "-h" || sqlstr == "-H" || sqlstr == "help" {
			cli.help()
			continue
		}
		//添加测试命令
		if sqlstr == "device_add" {
			cli.device_status_history_add_ext()
			continue
		}
		if sqlstr == "device_alarm_add" {
			cli.device_status_alarm_history_add()
			continue
		}
		if sqlstr == "quit" {
			fmt.Println("bye bye ")
			break
		}
		if len(sqls) > 6 {
			if string(sqls[:6]) == "select" || string(sqls[:4]) == "show" || string(sqls[:4]) == "desc" {
				//result set sql
				cli.query_sql(sqlstr)
			} else {
				//no result set sql
				cli.exec_sql(sqlstr)
			}
		}
	}
}

func (cli *Client) exec_sql(xsql string) {
	result, err := cli.dbconn.Exec(xsql)
	if err != nil {
		fmt.Println("failed to exec sql:", xsql, err)
		return
	}
	rowsaff, _ := result.RowsAffected()
	fmt.Println("RowsAffected:", rowsaff)
}

func (cli *Client) query_sql(xsql string) {
	rows, err := cli.dbconn.Query(xsql)
	if err != nil {
		fmt.Println("failed for query sql:", err)
		return
	}
	cols, err := rows.Columns()
	if err != nil {
		fmt.Println("failed for get columns:", err)
		return
	}
	colCount := len(cols)

	//fmt.Println(colCount, "\n", cols)
	for _, v := range cols {
		fmt.Printf("%s\t", v)
	}
	fmt.Println("\n----------------------------------------")

	values := make([]sql.NullString, colCount)
	oneRows := make([]interface{}, colCount)
	for k, _ := range values {
		oneRows[k] = &values[k] //将查询结果的返回地址绑定，这样才能变参获取数据
	}

	for rows.Next() {

		//扫描结果集，一定要在Next调用后，方可使用
		err = rows.Scan(oneRows...)
		if err != nil {
			fmt.Println("failed to Scan result set", err)
			break
		}
		//fmt.Println(values)
		for _, v := range values {
			if v.Valid {
				fmt.Printf("%s\t", v.String)
			} else {
				fmt.Printf("%s\t", "NULL")
			}
		}
		fmt.Println()
	}
}

//*********************************************************************************************************
//业务逻辑
const (
	WaterStatusFiveMinutesNum  = 12
	WaterStatusFourHoursNum    = 20
	WaterStatusFiveMinutesBase = 0
	WaterStatusFourHoursBase   = WaterStatusFiveMinutesNum
	WaterStatusNum             = WaterStatusFiveMinutesNum + WaterStatusFourHoursNum
	WaterArrayNum              = 3
)

type WaterAlarmInfo struct {
	xtype    int
	last_val [WaterStatusNum]float32
}

type WaterItem struct {
	sn              uint64
	wateraffairs_id uint64
}

//全局变量
var waterArray = [WaterArrayNum]WaterItem{
	{240100017667, 8},
	{267000000002, 10},
	{267000000003, 11},
}

// var waterArray = [WaterArrayNum]WaterItem{
// 	{240100017667, 8},
// 	{267000000002, 10},
// 	{267000000003, 11},
// 	{240100017674, 12},
// }

var levelArray = [3]string{
	"general",
	"important",
	"emergency",
}
var (
	line_num     int64  = 1
	is_alarming  int64  = 1
	alarm_type   int64  = 1
	alarm_id     int    = 1
	alarm_magic  string = "magic_test"
	device_magic int64  = 0xaabbccdd
	timeLayout   string = "2006-01-02 15:04:05"
	alarm_table  string = "tbl_wateraffairs_alarm_history"
	device_table string = "tbl_wateraffairs_device_status_history"
)

func (w *WaterAlarmInfo) GetInfoByIndex(index int) (int, int, string, string, string) {
	var wid int = 0
	var iid int = 0
	var level string = ""
	var value string = ""
	var reason string = ""
	var min float32 = 0
	var max float32 = 0
	var diff float32 = 0
	var alarm_min float32 = 0
	var alarm_max float32 = 0
	var step float32 = 0
	var probability int = 10

	switch index {
	//第一部分
	case 0:
		wid = 1
		iid = 1
		min = 64.7
		max = 147.7
		alarm_min = 97.2
		step = 0.1
		diff = max - min
		level = levelArray[rand.Intn(3)]

		//判断下有没有初始化上次的值
		for w.last_val[index] == 0 {
			if w.last_val[index] != 0 {
				break
			}
			w.last_val[index] = rand.Float32()*diff + min
		}
		if rand.Intn(2) == 0 {
			w.last_val[index] -= step
		} else {
			w.last_val[index] += step
		}
		if w.last_val[index] > max {
			w.last_val[index] = max
		}
		if w.last_val[index] < min {
			w.last_val[index] = min
		}
		value = fmt.Sprintf("%.2f", w.last_val[index])
		//判断是否需要报警
		reason = ""
		if w.last_val[index] < alarm_min {
			reason = "进水管流量低位"
		}
	case 1:
		wid = 1
		iid = 3
		min = 6.2
		max = 7.9
		alarm_min = 6.5
		alarm_max = 7.7
		step = 0.1
		diff = max - min
		level = levelArray[rand.Intn(3)]

		//判断下有没有初始化上次的值
		for w.last_val[index] == 0 {
			if w.last_val[index] != 0 {
				break
			}
			w.last_val[index] = rand.Float32()*diff + min
		}
		if rand.Intn(2) == 0 {
			w.last_val[index] -= step
		} else {
			w.last_val[index] += step
		}
		if w.last_val[index] > max {
			w.last_val[index] = max
		}
		if w.last_val[index] < min {
			w.last_val[index] = min
		}
		value = fmt.Sprintf("%.2f", w.last_val[index])
		//判断是否需要报警
		reason = ""
		if w.last_val[index] < alarm_min {
			reason = "进水管PH值低位"
		}
		if w.last_val[index] > alarm_max {
			reason = "进水管PH值高位"
		}
	case 2:
		wid = 1
		iid = 4
		min = 16.325
		max = 19.732
		alarm_max = 19.432
		step = rand.Float32()*(0.5-0.01) + 0.01
		diff = max - min
		level = levelArray[rand.Intn(3)]

		//判断下有没有初始化上次的值
		for w.last_val[index] == 0 {
			if w.last_val[index] != 0 {
				break
			}
			w.last_val[index] = rand.Float32()*diff + min
		}
		if rand.Intn(2) == 0 {
			w.last_val[index] -= step
		} else {
			w.last_val[index] += step
		}
		if w.last_val[index] > max {
			w.last_val[index] = max
		}
		if w.last_val[index] < min {
			w.last_val[index] = min
		}
		value = fmt.Sprintf("%.2f", w.last_val[index])

		if w.last_val[index] > alarm_max {
			reason = "进水管浊度高位"
		}
	case 3:
		wid = 1
		iid = 5
		level = levelArray[rand.Intn(3)]
		value = fmt.Sprintf("%d", (rand.Intn(probability)))

		reason = ""
		//这样来表示10分之1
		if value == "0" {
			reason = "进水电动开关关闭"
		} else {
			//开启不需要报警
			// reason = "进水电动开关开启"
			value = "1"
		}
	case 4:
		wid = 2
		iid = 8
		level = levelArray[rand.Intn(3)]
		value = fmt.Sprintf("%d", (rand.Intn(probability)))

		reason = ""
		if value == "0" {
			reason = "加药电动开关关闭"
		} else {
			// reason = "加药电动开关开启"
			value = "1"
		}
	case 5:
		wid = 4
		iid = 11
		level = levelArray[rand.Intn(3)]
		value = fmt.Sprintf("%d", (rand.Intn(probability)))

		reason = ""
		if value == "0" {
			reason = "过滤池反冲洗电动开关关闭"
		} else {
			// reason = "过滤池反冲洗电动开关开启"
			value = "1"
		}
	case 6:
		wid = 5
		iid = 13
		level = levelArray[rand.Intn(3)]
		value = fmt.Sprintf("%d", (rand.Intn(probability)))

		reason = ""
		if value == "0" {
			reason = "消毒设备电动开关关闭"
		} else {
			// reason = "消毒设备电动开关开启"
			value = "1"
		}
	case 7:
		wid = 7
		iid = 20

		min = 0.89
		max = 0.93
		diff = max - min
		//值直接取index的值,每次89%~92%
		level = levelArray[rand.Intn(3)]

		w.last_val[index] = w.last_val[0] * (rand.Float32()*diff + min)
		value = fmt.Sprintf("%.2f", w.last_val[index])
		reason = ""
	case 8:
		wid = 7
		iid = 27
		level = levelArray[rand.Intn(3)]

		min = 0.03
		max = 0.742
		alarm_max = 0.332
		step = rand.Float32()*(0.1-0.01) + 0.01
		diff = max - min
		level = levelArray[rand.Intn(3)]

		//判断下有没有初始化上次的值
		for w.last_val[index] == 0 {
			if w.last_val[index] != 0 {
				break
			}
			w.last_val[index] = rand.Float32()*diff + min
		}
		if rand.Intn(2) == 0 {
			w.last_val[index] -= step
		} else {
			w.last_val[index] += step
		}
		if w.last_val[index] > max {
			w.last_val[index] = max
		}
		if w.last_val[index] < min {
			w.last_val[index] = min
		}
		value = fmt.Sprintf("%.2f", w.last_val[index])

		reason = ""
		if w.last_val[index] > alarm_max {
			reason = "供水装置浊度高位"
		}
	case 9:
		wid = 7
		iid = 28
		min = 0.205
		max = 0.243
		diff = max - min
		level = levelArray[rand.Intn(3)]

		// alarm_min = 1.0
		alarm_max = 0.415
		step = rand.Float32()*(0.03-0.01) + 0.01

		//判断下有没有初始化上次的值
		for w.last_val[index] == 0 {
			if w.last_val[index] != 0 {
				break
			}
			w.last_val[index] = rand.Float32()
		}
		if rand.Intn(2) == 0 {
			w.last_val[index] -= step
		} else {
			w.last_val[index] += step
		}
		if w.last_val[index] > max {
			w.last_val[index] = max
		}
		if w.last_val[index] < min {
			w.last_val[index] = min
		}
		value = fmt.Sprintf("%.2f", w.last_val[index])

		reason = ""
		// if w.last_val[index] < alarm_min {
		// 	reason = "供水装置余氯低位"
		// }
		if w.last_val[index] > alarm_max {
			reason = "供水装置余氯高位"
		}
	case 10:
		wid = 7
		iid = 29
		min = 6.6
		max = 7.6
		diff = max - min
		level = levelArray[rand.Intn(3)]

		alarm_min = 6.8
		alarm_max = 7.4
		step = 0.1

		//判断下有没有初始化上次的值
		for w.last_val[index] == 0 {
			if w.last_val[index] != 0 {
				break
			}
			w.last_val[index] = rand.Float32()
		}
		if rand.Intn(2) == 0 {
			w.last_val[index] -= step
		} else {
			w.last_val[index] += step
		}
		if w.last_val[index] > max {
			w.last_val[index] = max
		}
		if w.last_val[index] < min {
			w.last_val[index] = min
		}
		value = fmt.Sprintf("%.2f", w.last_val[index])

		reason = ""
		if w.last_val[index] < alarm_min {
			reason = "供水装置PH值低位"
		}
		if w.last_val[index] > alarm_max {
			reason = "供水装置PH值高位"
		}
	case 11:
		wid = 2
		iid = 6
		min = 0.5
		max = 1.4
		step = 0.1
		diff = max - min
		level = levelArray[rand.Intn(3)]

		//判断下有没有初始化上次的值
		for w.last_val[index] == 0 {
			if w.last_val[index] != 0 {
				break
			}
			w.last_val[index] = rand.Float32()*diff + min
		}
		if rand.Intn(2) == 0 {
			w.last_val[index] -= step
		} else {
			w.last_val[index] += step
		}
		if w.last_val[index] > max {
			w.last_val[index] = max
		}
		if w.last_val[index] < min {
			w.last_val[index] = min
		}
		value = fmt.Sprintf("%.2f", w.last_val[index])

		//后面是第二部分
	case 12:
		wid = 1
		iid = 2
		min = 0.35
		max = 0.64
		step = 0.01
		diff = max - min
		level = levelArray[rand.Intn(3)]

		//判断下有没有初始化上次的值
		for w.last_val[index] == 0 {
			if w.last_val[index] != 0 {
				break
			}
			w.last_val[index] = rand.Float32()*diff + min
		}
		if rand.Intn(2) == 0 {
			w.last_val[index] -= step
		} else {
			w.last_val[index] += step
		}
		if w.last_val[index] > max {
			w.last_val[index] = max
		}
		if w.last_val[index] < min {
			w.last_val[index] = min
		}
		value = fmt.Sprintf("%.2f", w.last_val[index])
	case 13:
		wid = 3
		iid = 9
		min = 14.325
		max = 16.732
		step = 0.3
		diff = max - min
		level = levelArray[rand.Intn(3)]

		//判断下有没有初始化上次的值
		for w.last_val[index] == 0 {
			if w.last_val[index] != 0 {
				break
			}
			w.last_val[index] = rand.Float32()*diff + min
		}
		if rand.Intn(2) == 0 {
			w.last_val[index] -= step
		} else {
			w.last_val[index] += step
		}
		if w.last_val[index] > max {
			w.last_val[index] = max
		}
		if w.last_val[index] < min {
			w.last_val[index] = min
		}
		value = fmt.Sprintf("%.2f", w.last_val[index])
	case 14:
		wid = 4
		iid = 10
		min = 4.325
		max = 6.732
		step = 0.1
		diff = max - min
		level = levelArray[rand.Intn(3)]

		//判断下有没有初始化上次的值
		for w.last_val[index] == 0 {
			if w.last_val[index] != 0 {
				break
			}
			w.last_val[index] = rand.Float32()*diff + min
		}
		if rand.Intn(2) == 0 {
			w.last_val[index] -= step
		} else {
			w.last_val[index] += step
		}
		if w.last_val[index] > max {
			w.last_val[index] = max
		}
		if w.last_val[index] < min {
			w.last_val[index] = min
		}
		value = fmt.Sprintf("%.2f", w.last_val[index])
	case 15:
		wid = 5
		iid = 14
		min = 62.3
		max = 140.4
		step = 1
		diff = max - min
		level = levelArray[rand.Intn(3)]

		//判断下有没有初始化上次的值
		for w.last_val[index] == 0 {
			if w.last_val[index] != 0 {
				break
			}
			w.last_val[index] = rand.Float32()*diff + min
		}
		if rand.Intn(2) == 0 {
			w.last_val[index] -= step
		} else {
			w.last_val[index] += step
		}
		if w.last_val[index] > max {
			w.last_val[index] = max
		}
		if w.last_val[index] < min {
			w.last_val[index] = min
		}
		value = fmt.Sprintf("%.2f", w.last_val[index])
	case 16:
		wid = 6
		iid = 15
		min = 2.4
		max = 6.5
		step = 0.1
		diff = max - min
		level = levelArray[rand.Intn(3)]

		//判断下有没有初始化上次的值
		for w.last_val[index] == 0 {
			if w.last_val[index] != 0 {
				break
			}
			w.last_val[index] = rand.Float32()*diff + min
		}
		if rand.Intn(2) == 0 {
			w.last_val[index] -= step
		} else {
			w.last_val[index] += step
		}
		if w.last_val[index] > max {
			w.last_val[index] = max
		}
		if w.last_val[index] < min {
			w.last_val[index] = min
		}
		value = fmt.Sprintf("%.2f", w.last_val[index])
	case 17:
		wid = 6
		iid = 16
		min = 6.2
		max = 7.9
		step = 0.1
		diff = max - min
		level = levelArray[rand.Intn(3)]

		//判断下有没有初始化上次的值
		for w.last_val[index] == 0 {
			if w.last_val[index] != 0 {
				break
			}
			w.last_val[index] = rand.Float32()*diff + min
		}
		if rand.Intn(2) == 0 {
			w.last_val[index] -= step
		} else {
			w.last_val[index] += step
		}
		if w.last_val[index] > max {
			w.last_val[index] = max
		}
		if w.last_val[index] < min {
			w.last_val[index] = min
		}
		value = fmt.Sprintf("%.2f", w.last_val[index])
	case 18:
		wid = 6
		iid = 17
		min = 1.325
		max = 3.732
		step = 0.1
		diff = max - min
		level = levelArray[rand.Intn(3)]

		//判断下有没有初始化上次的值
		for w.last_val[index] == 0 {
			if w.last_val[index] != 0 {
				break
			}
			w.last_val[index] = rand.Float32()*diff + min
		}
		if rand.Intn(2) == 0 {
			w.last_val[index] -= step
		} else {
			w.last_val[index] += step
		}
		if w.last_val[index] > max {
			w.last_val[index] = max
		}
		if w.last_val[index] < min {
			w.last_val[index] = min
		}
		value = fmt.Sprintf("%.2f", w.last_val[index])
	case 19:
		wid = 6
		iid = 18
		min = 3.705
		max = 5.243
		step = 0.1
		diff = max - min
		level = levelArray[rand.Intn(3)]

		//判断下有没有初始化上次的值
		for w.last_val[index] == 0 {
			if w.last_val[index] != 0 {
				break
			}
			w.last_val[index] = rand.Float32()*diff + min
		}
		if rand.Intn(2) == 0 {
			w.last_val[index] -= step
		} else {
			w.last_val[index] += step
		}
		if w.last_val[index] > max {
			w.last_val[index] = max
		}
		if w.last_val[index] < min {
			w.last_val[index] = min
		}
		value = fmt.Sprintf("%.2f", w.last_val[index])
	case 20:
		wid = 6
		iid = 19
		min = 3.5
		max = 9.2
		step = 0.1
		diff = max - min
		level = levelArray[rand.Intn(3)]

		//判断下有没有初始化上次的值
		for w.last_val[index] == 0 {
			if w.last_val[index] != 0 {
				break
			}
			w.last_val[index] = rand.Float32()*diff + min
		}
		if rand.Intn(2) == 0 {
			w.last_val[index] -= step
		} else {
			w.last_val[index] += step
		}
		if w.last_val[index] > max {
			w.last_val[index] = max
		}
		if w.last_val[index] < min {
			w.last_val[index] = min
		}
		value = fmt.Sprintf("%.2f", w.last_val[index])
	case 21:
		wid = 7
		iid = 32
		min = 0.07
		max = 0.35
		step = 0.01
		diff = max - min
		level = levelArray[rand.Intn(3)]

		//判断下有没有初始化上次的值
		for w.last_val[index] == 0 {
			if w.last_val[index] != 0 {
				break
			}
			w.last_val[index] = rand.Float32()*diff + min
		}
		if rand.Intn(2) == 0 {
			w.last_val[index] -= step
		} else {
			w.last_val[index] += step
		}
		if w.last_val[index] > max {
			w.last_val[index] = max
		}
		if w.last_val[index] < min {
			w.last_val[index] = min
		}
		value = fmt.Sprintf("%.2f", w.last_val[index])
	case 22:
		wid = 7
		iid = 33
		level = levelArray[rand.Intn(3)]
		value = fmt.Sprintf("%d", (rand.Intn(probability)))

		if value == "0" {
			reason = "供水装置泵开关关闭"
		} else {
			// reason = "消毒设备电动开关开启"
			value = "1"
		}
	case 23:
		wid = 2
		iid = 34
		min = 192.7
		max = 225.6
		alarm_min = 193
		alarm_max = 220
		step = 1
		diff = max - min
		level = levelArray[rand.Intn(3)]

		//判断下有没有初始化上次的值
		for w.last_val[index] == 0 {
			if w.last_val[index] != 0 {
				break
			}
			w.last_val[index] = rand.Float32()*diff + min
		}
		if rand.Intn(2) == 0 {
			w.last_val[index] -= step
		} else {
			w.last_val[index] += step
		}
		if w.last_val[index] > max {
			w.last_val[index] = max
		}
		if w.last_val[index] < min {
			w.last_val[index] = min
		}
		value = fmt.Sprintf("%.2f", w.last_val[index])
		//判断是否需要报警
		reason = ""
		if w.last_val[index] < alarm_min {
			reason = "加药泵电压过低"
		}
		if w.last_val[index] > alarm_max {

		}
	case 24:
		wid = 2
		iid = 35
		min = 18.9
		max = 22.4
		alarm_min = 19
		alarm_max = 21
		step = 0.3
		diff = max - min
		level = levelArray[rand.Intn(3)]

		//判断下有没有初始化上次的值
		for w.last_val[index] == 0 {
			if w.last_val[index] != 0 {
				break
			}
			w.last_val[index] = rand.Float32()*diff + min
		}
		if rand.Intn(2) == 0 {
			w.last_val[index] -= step
		} else {
			w.last_val[index] += step
		}
		if w.last_val[index] > max {
			w.last_val[index] = max
		}
		if w.last_val[index] < min {
			w.last_val[index] = min
		}
		value = fmt.Sprintf("%.2f", w.last_val[index])
		//判断是否需要报警
		if w.last_val[index] < alarm_min {

		}
		if w.last_val[index] > alarm_max {
			reason = "加药泵电流过高"
		}
	case 25:
		wid = 2
		iid = 36
		min = 49.8
		max = 50.3
		step = 0.02
		diff = max - min
		level = levelArray[rand.Intn(3)]

		//判断下有没有初始化上次的值
		for w.last_val[index] == 0 {
			if w.last_val[index] != 0 {
				break
			}
			w.last_val[index] = rand.Float32()*diff + min
		}
		if rand.Intn(2) == 0 {
			w.last_val[index] -= step
		} else {
			w.last_val[index] += step
		}
		if w.last_val[index] > max {
			w.last_val[index] = max
		}
		if w.last_val[index] < min {
			w.last_val[index] = min
		}
		value = fmt.Sprintf("%.2f", w.last_val[index])
	case 26:
		wid = 5
		iid = 37
		min = 192.7
		max = 225.6
		alarm_min = 193
		alarm_max = 220
		step = 1
		diff = max - min
		level = levelArray[rand.Intn(3)]

		//判断下有没有初始化上次的值
		for w.last_val[index] == 0 {
			if w.last_val[index] != 0 {
				break
			}
			w.last_val[index] = rand.Float32()*diff + min
		}
		if rand.Intn(2) == 0 {
			w.last_val[index] -= step
		} else {
			w.last_val[index] += step
		}
		if w.last_val[index] > max {
			w.last_val[index] = max
		}
		if w.last_val[index] < min {
			w.last_val[index] = min
		}
		value = fmt.Sprintf("%.2f", w.last_val[index])
		//判断是否需要报警
		if w.last_val[index] < alarm_min {
			reason = "消毒泵电压过低"
		}
		if w.last_val[index] > alarm_max {

		}
	case 27:
		wid = 5
		iid = 38
		min = 18.9
		max = 22.4
		alarm_min = 19
		alarm_max = 21
		step = 0.3
		diff = max - min
		level = levelArray[rand.Intn(3)]

		//判断下有没有初始化上次的值
		for w.last_val[index] == 0 {
			if w.last_val[index] != 0 {
				break
			}
			w.last_val[index] = rand.Float32()*diff + min
		}
		if rand.Intn(2) == 0 {
			w.last_val[index] -= step
		} else {
			w.last_val[index] += step
		}
		if w.last_val[index] > max {
			w.last_val[index] = max
		}
		if w.last_val[index] < min {
			w.last_val[index] = min
		}
		value = fmt.Sprintf("%.2f", w.last_val[index])
		//判断是否需要报警
		if w.last_val[index] < alarm_min {

		}
		if w.last_val[index] > alarm_max {
			reason = "消毒泵电流过高"
		}
	case 28:
		wid = 5
		iid = 39
		min = 49.8
		max = 50.3
		step = 0.02
		diff = max - min
		level = levelArray[rand.Intn(3)]

		//判断下有没有初始化上次的值
		for w.last_val[index] == 0 {
			if w.last_val[index] != 0 {
				break
			}
			w.last_val[index] = rand.Float32()*diff + min
		}
		if rand.Intn(2) == 0 {
			w.last_val[index] -= step
		} else {
			w.last_val[index] += step
		}
		if w.last_val[index] > max {
			w.last_val[index] = max
		}
		if w.last_val[index] < min {
			w.last_val[index] = min
		}
		value = fmt.Sprintf("%.2f", w.last_val[index])
	case 29:
		wid = 7
		iid = 40
		min = 192.7
		max = 225.6
		alarm_min = 193
		alarm_max = 224
		step = 1
		diff = max - min
		level = levelArray[rand.Intn(3)]

		//判断下有没有初始化上次的值
		for w.last_val[index] == 0 {
			if w.last_val[index] != 0 {
				break
			}
			w.last_val[index] = rand.Float32()*diff + min
		}
		if rand.Intn(2) == 0 {
			w.last_val[index] -= step
		} else {
			w.last_val[index] += step
		}
		if w.last_val[index] > max {
			w.last_val[index] = max
		}
		if w.last_val[index] < min {
			w.last_val[index] = min
		}
		value = fmt.Sprintf("%.2f", w.last_val[index])
		//判断是否需要报警
		if w.last_val[index] < alarm_min {
			reason = "供水装置电压过低"
		}
		if w.last_val[index] > alarm_max {

		}
	case 30:
		wid = 7
		iid = 41
		min = 18.9
		max = 22.4
		alarm_min = 19
		alarm_max = 21
		step = 0.3
		diff = max - min
		level = levelArray[rand.Intn(3)]

		//判断下有没有初始化上次的值
		for w.last_val[index] == 0 {
			if w.last_val[index] != 0 {
				break
			}
			w.last_val[index] = rand.Float32()*diff + min
		}
		if rand.Intn(2) == 0 {
			w.last_val[index] -= step
		} else {
			w.last_val[index] += step
		}
		if w.last_val[index] > max {
			w.last_val[index] = max
		}
		if w.last_val[index] < min {
			w.last_val[index] = min
		}
		value = fmt.Sprintf("%.2f", w.last_val[index])
		//判断是否需要报警
		if w.last_val[index] < alarm_min {

		}
		if w.last_val[index] > alarm_max {
			reason = "供水装置电流过高"
		}
	case 31:
		wid = 7
		iid = 42
		min = 49.8
		max = 50.3
		step = 0.1
		diff = max - min
		level = levelArray[rand.Intn(3)]

		//判断下有没有初始化上次的值
		for w.last_val[index] == 0 {
			if w.last_val[index] != 0 {
				break
			}
			w.last_val[index] = rand.Float32()*diff + min
		}
		if rand.Intn(2) == 0 {
			w.last_val[index] -= step
		} else {
			w.last_val[index] += step
		}
		if w.last_val[index] > max {
			w.last_val[index] = max
		}
		if w.last_val[index] < min {
			w.last_val[index] = min
		}
		value = fmt.Sprintf("%.2f", w.last_val[index])
	default:
		os.Exit(0)
	}

	return wid, iid, level, value, reason
}

func (cli *Client) device_status_history_add_ext() {
	alarm_id = 0
	cli.device_status_history_add1()
	cli.device_status_history_add2()
}

func (cli *Client) device_status_history_add1() {
	var begin_time time.Time = time.Date(2020, 04, 14, 00, 00, 00, 00, time.Local) //开始时间
	var end_time time.Time = time.Date(2020, 05, 31, 23, 00, 00, 00, time.Local)   //结束时间,或者time.Now()
	var interval_time int64 = 5 * 60                                               //设备状态记录时间间隔最小时间5分钟
	cli.device_status_history_add(begin_time, end_time, interval_time, WaterStatusFiveMinutesBase, WaterStatusFiveMinutesNum)
}

func (cli *Client) device_status_history_add2() {
	var begin_time time.Time = time.Date(2020, 05, 21, 00, 00, 00, 00, time.Local) //开始时间
	var end_time time.Time = time.Date(2020, 05, 31, 23, 00, 00, 00, time.Local)   //结束时间,或者time.Now()
	var interval_time int64 = 4 * 60 * 60                                          //设备状态记录时间间隔最小时间5分钟
	cli.device_status_history_add(begin_time, end_time, interval_time, WaterStatusFourHoursBase, WaterStatusFourHoursNum)
}

type LastAlarm struct {
	valid   bool
	last_id int
}

func (cli *Client) device_status_history_add(begin_time time.Time, end_time time.Time, device_interval_min_time_sec int64, base int, num int) {
	btime := begin_time.Unix()
	etime := end_time.Unix()

	str := ""
	var build strings.Builder
	var max_add int = 30000
	var add_index int = 0

	var alarm_max_add int = 30000
	var alarm_add_index int = 0
	var alarm_build strings.Builder

	var alarm_num int = 0
	var status_num int = 0

	fmt.Println("goto device_status_history_add")
	var ai [WaterArrayNum]WaterAlarmInfo
	var last_alarm [WaterArrayNum][WaterStatusNum]LastAlarm
	for btime <= etime {
		for i := 0; i < WaterArrayNum; i++ {
			sn := waterArray[i].sn
			wateraffairs_id := waterArray[i].wateraffairs_id
			year := 0
			month := 0
			day := 0
			t := time.Unix(btime, 0)
			year = t.Year()
			month = int(t.Month())
			day = t.Day()
			dsttime := t.Format(timeLayout)
			for j := 0; j < num; j++ {
				work_part_id, alarm_items_id, alarm_level, alarm_value, alarm_reason := ai[i].GetInfoByIndex(j + base)
				dstvalue, _ := strconv.ParseFloat(alarm_value, 64)
				//先传alarm,要计算alarm_id
				device_alarm_id := 0
				if alarm_reason != "" {
					//表示有报警,需要添加报警
					//这里判断下,如果是连贯的报警,就不要添加新的报警信息了,直接用上次的
					if last_alarm[i][j].valid == false {
						device_alarm_id = alarm_id
						last_alarm[i][j].last_id = alarm_id
						if alarm_add_index == 0 {
							str = fmt.Sprintf("(%d, %d, %d, %d, %d, %d, %d, '%s', '%s', '%s', '%s', %d, %d, %d, '%s')", sn, is_alarming, alarm_type, alarm_items_id, wateraffairs_id, line_num, work_part_id, dsttime, alarm_level, alarm_value, alarm_reason, year, month, day, alarm_magic)
						} else {
							str = fmt.Sprintf(",(%d, %d, %d, %d, %d, %d, %d, '%s', '%s', '%s', '%s', %d, %d, %d, '%s')", sn, is_alarming, alarm_type, alarm_items_id, wateraffairs_id, line_num, work_part_id, dsttime, alarm_level, alarm_value, alarm_reason, year, month, day, alarm_magic)
						}
						alarm_add_index++
						alarm_id++
						alarm_num++
						alarm_build.WriteString(str)
					} else {
						//是连续添加的,则用上次的id
						device_alarm_id = last_alarm[i][j].last_id
					}
					last_alarm[i][j].valid = true
				} else {
					last_alarm[i][j].valid = false
				}
				if add_index == 0 {
					str = fmt.Sprintf("(%d, %d, %d, %d, '%s', %d, %f, %d, %d, %d, %d)", sn, wateraffairs_id, line_num, work_part_id, dsttime, alarm_items_id, dstvalue, year, month, day, device_alarm_id)
				} else {
					str = fmt.Sprintf(",(%d, %d, %d, %d, '%s', %d, %f, %d, %d, %d, %d)", sn, wateraffairs_id, line_num, work_part_id, dsttime, alarm_items_id, dstvalue, year, month, day, device_alarm_id)
				}
				add_index++
				status_num++
				build.WriteString(str)
			}
		}
		if add_index >= max_add {
			fmt.Println("goto add device_status")
			dststr := fmt.Sprintf("insert into %s(sn, wateraffairs_id, line_num, work_part_id, push_time, items_id, value, year_int, month_int, day_int, alarm_id) values %s", device_table, build.String())
			cli.exec_sql(dststr)
			add_index = 0
			build.Reset()
		}
		if alarm_add_index >= alarm_max_add {
			fmt.Println("goto add device_alarm")
			dststr := fmt.Sprintf("insert into %s(sn, is_alarming, alarm_type, alarm_items_id, wateraffairs_id, line_num, work_part_id, alarm_time, alarm_level, alarm_value, alarm_reason, year_int, month_int, day_int, processor) values %s", alarm_table, alarm_build.String())
			cli.exec_sql(dststr)
			alarm_add_index = 0
			alarm_build.Reset()
		}
		btime += device_interval_min_time_sec
	}
	if add_index > 0 {
		fmt.Println("goto add device_status")
		dststr := fmt.Sprintf("insert into %s(sn, wateraffairs_id, line_num, work_part_id, push_time, items_id, value, year_int, month_int, day_int, alarm_id) values %s", device_table, build.String())
		cli.exec_sql(dststr)
		add_index = 0
		build.Reset()
	}
	if alarm_add_index > 0 {
		fmt.Println("goto add device_alarm")
		dststr := fmt.Sprintf("insert into %s(sn, is_alarming, alarm_type, alarm_items_id, wateraffairs_id, line_num, work_part_id, alarm_time, alarm_level, alarm_value, alarm_reason, year_int, month_int, day_int, processor) values %s", alarm_table, alarm_build.String())
		cli.exec_sql(dststr)
		alarm_add_index = 0
		alarm_build.Reset()
	}
	fmt.Println("exit device_status_history_add alarm_num=", alarm_num, " status_num=", status_num)
}

type alarm_info struct {
	work_part_id   int
	alarm_items_id int
	reason         string
	reason1        string
}

func (cli *Client) device_status_alarm_history_add() {
	var begin_time time.Time = time.Date(2020, 04, 14, 00, 00, 00, 00, time.Local) //开始时间
	var end_time time.Time = time.Date(2020, 05, 31, 23, 00, 00, 00, time.Local)   //结束时间,或者time.Now()
	btime := int(begin_time.Unix())
	etime := int(end_time.Unix())
	oneday := 24 * 60 * 60

	var alarm_max_add int = 1 //30000
	var alarm_add_index int = 0
	var alarm_build strings.Builder

	rand.Seed(time.Now().Unix())
	fmt.Println("goto device_status_alarm_history_add")

	rand_num := 0
	min := 3
	max := 10
	diff := max - min
	nexttime := 0
	// 加药箱异常开启		work_part_id=8	alarm_items_id(items_id)=22		value=1		alarm_image="" (每天生成3~9个)
	// 配电箱异常开启		work_part_id=9	alarm_items_id(items_id)=24		value=1		alarm_image="" (每天生成3~9个)
	// 操作间有人闯入		work_part_id=11	alarm_items_id(items_id)=30		value=1		alarm_image="" (每天生成3~9个)
	// 机房有人闯入		work_part_id=13	alarm_items_id(items_id)=31		value=1		alarm_image="" (每天生成3~9个)
	alarm_type_array := [4]alarm_info{
		{8, 22, "加药箱异常开启", "加药箱异常开启"},
		{9, 24, "配电箱异常开启", "配电箱异常开启"},
		{11, 30, "操作间红外探测到有人闯入", "操作间摄像头抓拍到有人闯入"},
		{13, 31, "机房红外探测到有人闯入", "机房摄像头抓拍到有人闯入"}}
	for i := 0; i < len(waterArray); i++ {
		nexttime = btime
		sn := waterArray[i].sn
		wateraffairs_id := waterArray[i].wateraffairs_id
		alarm_add_index = 0
		//每个设备来一下
		for nexttime <= etime {
			for n := 0; n < len(alarm_type_array); n++ {
				work_part_id := alarm_type_array[n].work_part_id
				alarm_items_id := alarm_type_array[n].alarm_items_id
				reason := alarm_type_array[n].reason
				if rand.Intn(2) == 1 {
					reason = alarm_type_array[n].reason1
				}
				rand_num = rand.Intn(diff) + min
				for j := 0; j < rand_num; j++ {
					// alarm_image := ""
					alarm_value := "1"
					atime := int(rand.Intn(oneday))
					t := time.Unix(int64(atime+nexttime), 0)
					year := t.Year()
					month := int(t.Month())
					day := t.Day()
					dsttime := t.Format(timeLayout)
					str := ""
					if alarm_add_index == 0 {
						str = fmt.Sprintf("(%d, %d, %d, %d, %d, %d, %d, '%s', '%s', %d, %d, %d, '%s')", sn, is_alarming, alarm_type, alarm_items_id, wateraffairs_id, line_num, work_part_id, dsttime, alarm_value, year, month, day, reason)
					} else {
						str = fmt.Sprintf(",(%d, %d, %d, %d, %d, %d, %d, '%s', '%s', %d, %d, %d, '%s')", sn, is_alarming, alarm_type, alarm_items_id, wateraffairs_id, line_num, work_part_id, dsttime, alarm_value, year, month, day, reason)
					}
					alarm_add_index++
					alarm_build.WriteString(str)
				}
			}

			nexttime += oneday
		}
		if alarm_add_index >= alarm_max_add {
			fmt.Println("goto add device_alarm")
			dststr := fmt.Sprintf("insert into %s(sn, is_alarming, alarm_type, alarm_items_id, wateraffairs_id, line_num, work_part_id, alarm_time, alarm_value, year_int, month_int, day_int, alarm_reason) values %s", alarm_table, alarm_build.String())
			cli.exec_sql(dststr)
			alarm_add_index = 0
			alarm_build.Reset()
		}
	}
	if alarm_add_index > 0 {
		fmt.Println("goto add device_alarm")
		dststr := fmt.Sprintf("insert into %s(sn, is_alarming, alarm_type, alarm_items_id, wateraffairs_id, line_num, work_part_id, alarm_time, alarm_value, year_int, month_int, day_int, alarm_reason) values %s", alarm_table, alarm_build.String())
		fmt.Println("dststr=", dststr)
		cli.exec_sql(dststr)
		alarm_add_index = 0
		alarm_build.Reset()
	}
}

func (cli *Client) help() {
	fmt.Println("Usage:")
	fmt.Println("\t device_add")
	fmt.Println("\t device_alarm_add")
	fmt.Println("\t quit")
}

func main() {
	//cli := NewClient("ijmaster", "ijjazhang", "irext_new", "tcp(10.135.255.204:3307)")//测试服务器红外编码库
	// cli := NewClient("ijmaster", "ijjazhang", "ijdbs", "tcp(10.10.9.13:3306)")//测试密码服务器
	rand.Seed(time.Now().Unix())
	cli := NewClient("root", "www.galaxywind.com_ifanscloud.com", "wateraffairs_info", "tcp(10.133.17.56:3306)") //水务测试服务器
	if cli.Conn() != nil {
		log.Panic("failed to conn to mysql ")
	}
	cli.Run()
}
